package com.letu.aopcache.manager;

import com.letu.annotation.annotation.cache.Cache;
import com.letu.aopcache.MethodCacheKeyBuilder;
import com.letu.aopcache.clone.ICloner;
import com.letu.aopcache.model.AutoLoadConfig;
import com.letu.aopcache.model.CacheKeyTO;
import com.letu.aopcache.model.CacheWrapper;
import com.letu.aopcache.model.MethodMsg;
import com.letu.aopcache.parser.AbstractScriptParser;
import com.letu.aopcache.util.CacheUtil;
import com.letu.aopcache.util.MSetParam;
import com.letu.cache.repository.CacheOps;
import com.letu.cache.repository.CaffeineCacheOps;
import com.letu.core.model.CacheKey;
import com.letu.core.model.CacheKeyBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * 缓存关联关系 管理类
 */
@Slf4j
public class TableCacheManager {

    private final ICacheManager cacheManager;

    private final AutoLoadConfig config;

    private final ICloner cloner;

    private final CacheOps cacheOps;


    private final CaffeineCacheOps caffeineCacheOps;


    /**
     * 表达式解析器
     */
    private final AbstractScriptParser scriptParser;


    public TableCacheManager(ICacheManager cacheManager, AbstractScriptParser scriptParser, AutoLoadConfig config,
                             ICloner cloner, CacheOps cacheOps,CaffeineCacheOps caffeineCacheOps) throws IllegalArgumentException {
        if (null == cacheManager) {
            throw new IllegalArgumentException("cacheManager is null");
        }
        if (null == cloner) {
            throw new IllegalArgumentException("cloner is null");
        }
        if (null == scriptParser) {
            throw new IllegalArgumentException("scriptParser is null");
        }
        this.cacheManager = cacheManager;
        this.config = config;
        this.cloner = cloner;
        this.scriptParser = scriptParser;
        this.cacheOps = cacheOps;
        this.caffeineCacheOps = caffeineCacheOps;
    }


    /**
     * 全表缓存
     *
     * @param cache        缓存自定义注解
     * @param methodMsg    方法基础信息
     * @param cacheWrapper 返回值类
     * @throws Exception
     */
    public void writeCache(Cache cache, MethodMsg methodMsg, CacheWrapper<Object> cacheWrapper) throws Exception {
        if (null == cacheWrapper || cacheWrapper.getIds() == null || cacheWrapper.getIds().isEmpty()) {
            return;
        }
        //灯灯所属的key规范
        //缓存架构规范
        CacheKeyBuilder cacheKeyBuilder = methodMsg.getCacheKeyBuilder();
        for (Object object : cacheWrapper.getObjectList()) {
            Long l = CacheUtil.getIdInvok(object);
            CacheKey cacheKey = cacheKeyBuilder.key(l);
            Object entityObj = null;
            try {
                entityObj = cacheOps.get(cacheKey);
            } catch (Exception e) {
                log.error("redis 数据解析失败，则删除key，可能是表结构变了导致");
                cacheOps.del(cacheKey.getKey());
                entityObj = null;
                log.error(e.getMessage(), e);
            }
            if (entityObj == null) {
                //添加到缓存
                cacheOps.set(cacheKey, object);
            }
        }
    }

    /**
     * 全表缓存
     *
     * @param cache        缓存自定义注解
     * @param methodMsg    方法基础信息
     * @param cacheWrapper 返回值类
     * @throws Exception
     */
    public void writeCacheOfCaffeine(Cache cache, MethodMsg methodMsg, CacheWrapper<Object> cacheWrapper) throws Exception {
        if (null == cacheWrapper || cacheWrapper.getIds() == null || cacheWrapper.getIds().isEmpty()) {
            return;
        }
        //灯灯所属的key规范
        //缓存架构规范
        CacheKeyBuilder cacheKeyBuilder = methodMsg.getCacheKeyBuilder();
        for (Object object : cacheWrapper.getObjectList()) {
            Long l = CacheUtil.getIdInvok(object);
            CacheKey cacheKey = cacheKeyBuilder.key(l);
            Object entityObj = null;
            try {
                entityObj = caffeineCacheOps.get(cacheKey);
            } catch (Exception e) {
                log.error("redis 数据解析失败，则删除key，可能是表结构变了导致");
                caffeineCacheOps.del(cacheKey.getKey());
                entityObj = null;
                log.error(e.getMessage(), e);
            }
            if (entityObj == null) {
                //添加到缓存
                caffeineCacheOps.set(cacheKey, object);
            }
        }
    }
    /**
     * 查询关联关系缓存
     *
     * @param cacheWrapper 返回值类
     * @throws Exception
     */
    public List<Object> queryCache(MethodMsg methodMsg, CacheWrapper<Object> cacheWrapper) throws Exception {
        if (null == cacheWrapper || cacheWrapper.getIds() == null
                || cacheWrapper.getIds().isEmpty()) {
            return null;
        }
        CacheKeyBuilder cacheKeyBuilder = methodMsg.getCacheKeyBuilder();
        List<CacheKey> cacheKeyList = new ArrayList<>();
        for (Long id : cacheWrapper.getIds()) {
            cacheKeyList.add(cacheKeyBuilder.key(id));
        }
        return cacheOps.mGetByCacheKey(cacheKeyList);
    }



    /**
     * 查询关联关系缓存
     *
     * @param cacheWrapper 返回值类
     * @throws Exception
     */
    public List<Object> queryCacheOfCaffeine(MethodMsg methodMsg, CacheWrapper<Object> cacheWrapper) throws Exception {
        if (null == cacheWrapper || cacheWrapper.getIds() == null
                || cacheWrapper.getIds().isEmpty()) {
            return null;
        }
        List<Object> list = new ArrayList<>();

        CacheKeyBuilder cacheKeyBuilder = methodMsg.getCacheKeyBuilder();
        for (Long id : cacheWrapper.getIds()) {
            Object object = caffeineCacheOps.get(cacheKeyBuilder.key(id));
            list.add(object);
        }
        return list;
    }
}
